package com.scribd
{
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	
	import mx.controls.SWFLoader;
	import mx.core.UIComponent;
	import flash.system.Security;

	[Event (name="iPaperApiReady", type="flash.events.Event")]
	[Event (name="iPaperDocumentReady", type="flash.events.Event")]
	
	/**
	 * 
	 * The Scribd IPaper Flex API
	 * @author hoisie@scribd.com
	 * 
	 */
	public class IPaper extends UIComponent
	{
		// Loading Variables
		private var ipaperLoader:URLLoader;
		private var swfLoader:SWFLoader;
		private var _viewerUrl:String = "http://localhost:8080/Preloader.swf";
		//private var _viewerUrl:String = "http://documents.scribd.com/ScribdViewer.swf";
		private var _publisherId:String;
		private var _currentPage:int;
		private var _zoom:Number;
		private var _viewMode:String;
		
		//Ipaper variables
		private var _api:Object;
		private var spriteReady:Boolean;
		
		public static const viewModes:Array = ["list", "slide", "book", "tile"];
		
		private function get api():Object
		{
			return _api || (swfLoader && swfLoader.content && swfLoader.content['api']);
		}

		public function get publisherId():String
		{
			return _publisherId;
		}
		
		public function set publisherId(value:String):void
		{
			this._publisherId = value;
		}
		
		/**
		 * The location of the IPaper SWF. 
		 * @return the viewer url
		 * 
		 */
		public function get viewerUrl():String
		{
			return _viewerUrl;
		}
		
		public function set viewerUrl(value:String):void
		{
			this._viewerUrl = value;
		}
		
		/**
		 * The page count of the current document 
		 * @return 
		 * 
		 */
		public function get pageCount():int
		{
			if (!api)
			{
				throw new Error("IPaper not initialized");
			}
			return api.getPageCount();
		}
		
		[Bindable]
		/**
		 * The current page of the document.  
		 * @return 
		 * 
		 */
		public function get currentPage():int
		{
			if (!api)
			{
				return 0;
			}

			return _currentPage;
		}
		
		public function set currentPage(value:int):void
		{
			if (!api)
			{
				return;
			}
			
			if (value != api.getCurrentPage())
			{
				api.setCurrentPage(value);
			}
			_currentPage = value;
			
		}

		[Bindable]
		/**
		 * A number which represents the zoom value. A value of 1.00 is 100% zoom.  
		 * @return 
		 * 
		 */
		public function get zoom():Number
		{
			if (!api)
			{
				return 0;
			}
			return _zoom;
		}
		
		public function set zoom(value:Number):void
		{
			if (!api)
			{
				return;
			}
			if (value != api.getZoom())
			{
				api.setZoom(value);
			}
			_zoom = value;
			
		}
		
		[Bindable]
		/**
		 * The current view mode of the document. Possible values are "list", "slideshow", "book", and "tile" 
		 * @return 
		 * 
		 */
		public function get viewMode():String
		{
			if (!api)
			{
				return "None";
			}
			return _viewMode;
		}
		
		public function set viewMode(value:String):void
		{
			if (!api)
			{
				return;
			}
			
			if (value != api.getViewMode())
			{
				api.setViewMode(value);
			}
			
			_viewMode = value;
		}
		
		public function IPaper()
		{
			super();
		}
		
		protected override function createChildren():void
		{
			super.createChildren();
			this.loadSwf();
		}
		
		protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			
			if (api)
			{
				api.setDimensions(unscaledWidth, unscaledHeight);
			}
			else if (spriteReady)
			{
				swfLoader.content['setDimensions'](unscaledWidth, unscaledHeight);
			}
		}
		
		private function loadSwf():void
		{
			swfLoader = new SWFLoader();
			
			swfLoader.scaleContent = false;
			swfLoader.maintainAspectRatio = false;
			swfLoader.addEventListener(Event.INIT, onSwfInit);
			var domain:ApplicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
			swfLoader.loaderContext = new LoaderContext( false, domain, SecurityDomain.currentDomain);
			var params:Array = [
				"hide_full_screen_button=true",

			]

			_viewerUrl+='?';
			_viewerUrl+=params.join('&');

			swfLoader.load(_viewerUrl);
			
		}
			
		private function onSwfInit(event:Event):void
		{
			this.addChild( swfLoader.content );
			swfLoader.content.addEventListener("spriteReady", onSpriteReady);
			swfLoader.content.addEventListener("apiReady", apiReady);
		}
		
		private function onSpriteReady(event:Event):void
		{
			this.spriteReady = true;
			this.invalidateSize();
			this.invalidateDisplayList();
		}
		
		private function apiReady(event:Event):void
		{
			_api = swfLoader.content['api'];
			api.addEventListener("documentReady", documentReady);
			api.addEventListener("zoomChanged", function (e:Event):void { zoom = e['data'] });
			api.addEventListener("viewModeChanged", function (e:Event):void { viewMode = e['data'] });
			api.addEventListener("pageChanged", function (e:Event):void { currentPage = e['data'] });
			
			this.invalidateSize();
			this.invalidateDisplayList();
			
			dispatchEvent(new Event("iPaperApiReady"));
		}
		
		private function documentReady(event:Event):void
		{
			currentPage = api.getCurrentPage();
			zoom = api.getZoom();
			viewMode = api.getViewMode();
		}
		
		/**
		 * Loads a document given a documentId and an access key.  
		 * @param documentId
		 * @param accessKey
		 * 
		 */
		public function loadDocument(documentId:Number, accessKey:String):void
		{
			if (!api)
			{
				return;
			}	
			
			api.loadDocument(documentId, accessKey);
		}
		
		/**
		 * Loads a document from a url.  
		 * @param url
		 * @param publisherId
		 * 
		 */
		public function loadDocumentFromUrl(url:String, publisherId:String):void
		{
			if (!api)
			{
				return;
			}	
			
			api.loadDocumentFromUrl(url, publisherId);
		}
		
	}
}